﻿using MobiSms.DataModel;
using MobiSms.Enums;
using MobiSms.Library;
using MobiSms.Library.Extensions;
using System;
using System.Linq;
using System.Windows;
using System.Windows.Input;

namespace MobiSms.ViewModel
{
    public class ReplyDetailsViewModel : MainViewModel
    {
        public ReplyDetailsViewModel()
        {
            SoapClient.SendSMSCompleted -= SendSMSCompleted;
            SoapClient.SendSMSCompleted += SendSMSCompleted;

            NewMessageToSend.ValueChanged -= NewMessageValueChanged;
            NewMessageToSend.ValueChanged += NewMessageValueChanged;
        }

        #region Properties
        private string _guid;
        public string Guid
        {
            get { return _guid; }
            set
            {
                _guid = value;
                RaisePropertyChanged(() => Guid);
                if (!string.IsNullOrWhiteSpace(Guid))
                {
                    GetReplyInfo(Guid);
                }
            }
        }

        private ReplyInfo _currentReply;
        public ReplyInfo CurrentReply
        {
            get { return _currentReply; }
            set
            {
                _currentReply = value;
                RaisePropertyChanged(() => CurrentReply);
            }
        }

        private SerialInfo _selectedSerial;
        public SerialInfo SelectedSerial
        {
            get { return _selectedSerial; }
            set
            {
                _selectedSerial = value;
                RaisePropertyChanged(() => SelectedSerial);
                if (SelectedSerial != null)
                {
                    NewMessageToSend.Signature = SelectedSerial.Signature;
                }
                RaisePropertyChanged(() => SendCommand);
            }
        }

        private MessageInfo _newMessageToSend = new MessageInfo();
        public MessageInfo NewMessageToSend
        {
            get { return _newMessageToSend; }
            set
            {
                _newMessageToSend = value;
                RaisePropertyChanged(() => NewMessageToSend);
                NewMessageToSend.ValueChanged -= NewMessageValueChanged;
                NewMessageToSend.ValueChanged += NewMessageValueChanged;
                RaisePropertyChanged(() => TotleSendCount);
            }
        }

        public int TotleSendCount
        {
            get
            {
                if (NewMessageToSend.Content.Length == 0)
                {
                    return 0;
                }

                int contentLength = NewMessageToSend.Content.Length + NewMessageToSend.Signature.Length + 2;

                if (contentLength <= 70)
                {
                    return 1;
                }
                else
                {
                    return (contentLength + 64) / 65;
                }
            }
        }

        private Visibility _replyPanelVisibility = Visibility.Collapsed;
        public Visibility ReplyPanelVisibility
        {
            get { return _replyPanelVisibility; }
            set
            {
                _replyPanelVisibility = value;
                RaisePropertyChanged(() => ReplyPanelVisibility);
                RaisePropertyChanged(() => DetailPanelVisibility);
            }
        }

        public Visibility DetailPanelVisibility
        {
            get
            {
                return ReplyPanelVisibility == Visibility.Visible ? Visibility.Collapsed : Visibility.Visible;
            }
        } 
        #endregion

        #region Events & Methods
        private void GetReplyInfo(string guid)
        {
            if (Database.CollectionOfReplies.Count() > 0)
            {
                CurrentReply = Database.CollectionOfReplies.FirstOrDefault(r => r.Guid == guid);
                CurrentReply.Status = ReplyMessageStatusValue.Read;
                Submit(); 
                RaisePropertyChanged(() => DeleteCommand);
            }
        }

        private void Remove(ReplyInfo entity)
        {
            Database.CollectionOfReplies.DeleteOnSubmit(entity);
            Submit();
            NavigateBack();
        }

        private void SendSMSCompleted(object sender, SendSMSCompletedEventArgs e)
        {
            if (e.Error == null)
            {
                if (e.Result.code == 0)
                {
                    NewMessageToSend.SendId = e.Result.sendid;
                    NewMessageToSend.Status = MessageStatus.Succeed;
                    
                    SerialInfo serial = Database.CollectionOfSerialNumbers.FirstOrDefault(s => s.SerialNumber == SelectedSerial.SerialNumber);
                    serial.SentCount += 1;
                }
                else
                {
                    ShowResult<ResultCodeValue>(e.Result.code);
                    //MessageBox.Show(((ResultCodeValue)e.Result.code).ToString());
                }
            }
            else
            {
                MessageBox.Show(e.Error.Message);
            }

            NewMessageToSend.Time = DateTime.Now;

            Database.CollectionOfMessages.InsertOnSubmit(NewMessageToSend);

            Database.CollectionOfMobiles.InsertOnSubmit(new MessageMobileInfo()
            {
                Mobile = CurrentReply.Mobile,
                MessageGuid = NewMessageToSend.Guid,
                SendId = e.Result.sendid,
                Time = DateTime.Now
            });

            Submit();
        }

        private void NewMessageValueChanged(object sender, PropertyArgs e)
        {
            RaisePropertyChanged(() => NewMessageToSend);
            RaisePropertyChanged(() => TotleSendCount);
            RaisePropertyChanged(() => SendCommand);
        }
        #endregion

        #region Commands
        public ICommand DeleteCommand
        {
            get
            {
                return new GenericCommand()
                {
                    CanExecuteCallback = delegate { return CurrentReply != null; },
                    ExecuteCallback = delegate
                    {
                        if (MessageBox.Show(Application.Current.FindResource<string>(LanguageKeys.IDS_NOTIFICATION_DELETE_COMFIRM_BODY), Application.Current.FindResource<string>(LanguageKeys.IDS_NOTIFICATION_DELETE_COMFIRM_TITLE), MessageBoxButton.OKCancel) == MessageBoxResult.OK)
                        {
                            Remove(CurrentReply);
                        }
                    }
                };
            }
        }

        public ICommand OpenReplyPanelCommand
        {
            get
            {
                return new GenericCommand()
                {
                    //CanExecuteCallback = delegate { return CurrentReply != null; },
                    ExecuteCallback = delegate
                    {
                        ReplyPanelVisibility = Visibility.Visible;
                    }
                };
            }
        }

        public ICommand CancelCommand
        {
            get
            {
                return new GenericCommand()
                {
                    ExecuteCallback = delegate
                    {
                        ReplyPanelVisibility = Visibility.Collapsed;
                    }
                };
            }
        }

        public ICommand SendCommand
        {
            get
            {
                return new GenericCommand()
                {
                    CanExecuteCallback = delegate { return SelectedSerial != null && NewMessageToSend.Content.Length > 0 && CurrentReply != null; },
                    ExecuteCallback = delegate
                    {
                        SoapClient.SendSMSAsync(SelectedSerial.SerialNumber, SelectedSerial.Password, "content", CurrentReply.Mobile, "ext", "", "N", "");
                    }
                };
            }
        } 
        #endregion
    }
}
